package org.dtrd.modules.record.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.dtrd.common.util.DateUtils;
import org.dtrd.config.system.Constant;
import org.dtrd.config.system.Constant.RecordType;
import org.dtrd.modules.achievement.service.IDtrdEntRdSigninRecordService;
import org.dtrd.modules.record.entity.bean.CheckinRecord;
import org.dtrd.modules.record.entity.bean.SportBean;
import org.dtrd.modules.record.entity.po.DtrdEntRdSigninSportRecord;
import org.dtrd.modules.record.mapper.DtrdEntRdSportRecordMapper;
import org.dtrd.modules.record.service.ISportRecordService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 萧
 * @date:2021-08-22
 **/
@Service
@DS("multi-datasource1")
@Slf4j
public class SportRecordServiceImpl extends ServiceImpl<DtrdEntRdSportRecordMapper, DtrdEntRdSigninSportRecord> implements ISportRecordService {

    @Autowired
    private IDtrdEntRdSigninRecordService signinRecordService;

    @Override
    public DtrdEntRdSigninSportRecord transformRecord(CheckinRecord checkinRecord) {
        DtrdEntRdSigninSportRecord dt = new DtrdEntRdSigninSportRecord().init();
        dt.setSportRecordRemark(checkinRecord.getRemark());
        dt.setSportRecordStep(checkinRecord.getSportValue());
        dt.setSportRecordSteptype(checkinRecord.getSportType());
        dt.setSportRecordPowerDescribe(checkinRecord.getSportPowerDesc());
        dt.setPatientId(checkinRecord.getPatientId());
        dt.setRecordTime(parseStringAsDateTime(checkinRecord.getRecordTime()));
        dt.setRecordDate(parseStringAsDate(checkinRecord.getRecordTime()));
        dt.setRecordPhoto(checkinRecord.getImages());
        return dt;
    }

    @Override
    public CheckinRecord transformPO(DtrdEntRdSigninSportRecord po) {
        if (po == null) {
            return null;
        }
        CheckinRecord checkinRecord = new CheckinRecord();
        checkinRecord.setRecordTime(DateUtils.formatTime(po.getRecordTime()));
        checkinRecord.setRecordTimeHm(DateUtils.formatShortTime(po.getRecordTime()));
        checkinRecord.setDataId(po.getDataId());
        checkinRecord.setImages(po.getRecordPhoto());
        checkinRecord.setPatientId(po.getPatientId());
        checkinRecord.setRecordType(Constant.RecordType.SPORT.getType());
        checkinRecord.setRecordTypeName(Constant.RecordType.SPORT.getName());
        checkinRecord.setRemark(po.getSportRecordRemark());
        return checkinRecord;
    }

    @Override
    public LambdaQueryWrapper<DtrdEntRdSigninSportRecord> generateSelectRecordByDateQuery(Integer patientId,String date, Integer subType) {
        LambdaQueryWrapper<DtrdEntRdSigninSportRecord> query = new LambdaQueryWrapper<>();
        query.eq(DtrdEntRdSigninSportRecord::getIsDel, 0).eq(DtrdEntRdSigninSportRecord::getPatientId,patientId).eq(DtrdEntRdSigninSportRecord::getRecordDate, date);
        return query;
    }

    @Override
    public boolean saveOrUpdateSportRecord(SportBean sportBean) {
        DtrdEntRdSigninSportRecord po = new DtrdEntRdSigninSportRecord();
        if (sportBean.getDataId() == null){
            po = po.init();
        }
        po.parseFromDTO(sportBean);
        LambdaUpdateWrapper<DtrdEntRdSigninSportRecord> wrapper = Wrappers.lambdaUpdate(DtrdEntRdSigninSportRecord.class)
                .eq(DtrdEntRdSigninSportRecord::getPatientId, sportBean.getPatientId())
                .eq(DtrdEntRdSigninSportRecord::getRecordDate, po.getRecordDate());
        boolean result = saveOrUpdate(po, wrapper);
        log.info("SportRecordServiceImpl.saveOrUpdateSportRecord.[sportBean] after save patientId=" + po.getPatientId() + "; result=" + result + "; dataId=" + po.getDataId());
        if (po.getDataId() == null) {
            po = getOne(wrapper);
        }
        // 补充打卡
        signinRecordService.saveSigninRecord(po.getDataId(), 0, mapper ->
                mapper.apply(sportBean.getPatientId())
                        .withRecordType(RecordType.SPORT.getType())
                        .withRecordTime(sportBean.getRecordTime())
                        .withRecordValue(sportBean.getSportRecordStep()+"")
                        .withRecordDesc(sportBean.getSportRecordPowerDescribe())
                        .withRemark(sportBean.getSportRecordRemark())
                        .withImages(sportBean.getRecordPhoto())
                        .build()
        );
//        Date recordDate = sportRecord.getRecordDate();
//        DtrdEntRdSigninSportRecord po = getOne(wrapper);
//        signinRecordService.saveSigninRecord(po.getDataId(), sportBean.getPatientId(),
//                Constant.RecordType.SPORT.getType(), 0,
//                DateUtils.formatDate(recordDate, DateUtils.date_sdf.get().toPattern()));
        return result;
    }

    @Override
    public int getSportRecordCountByDateRange(Integer patientId, String startDate, String endDate) {
        LambdaQueryWrapper<DtrdEntRdSigninSportRecord> queryWrapper = getBasicQueryWrapper()
                .eq(DtrdEntRdSigninSportRecord::getPatientId, patientId)
                .ge(DtrdEntRdSigninSportRecord::getRecordDate, startDate)
                .le(DtrdEntRdSigninSportRecord::getRecordDate, endDate)
                .groupBy(DtrdEntRdSigninSportRecord::getRecordDate);
        List<DtrdEntRdSigninSportRecord> list = list(queryWrapper);
        return list.size();
    }

    @Override
    public List<SportBean> getSportRecordListByDateRange(Integer patientId, String startDate, String endDate, Integer page, Integer pageSize) {
        // 查询日期范围内的所有记录
        List<DtrdEntRdSigninSportRecord> sportRecords = baseMapper.selectSportList(patientId, startDate, endDate);
        int pageStart = (page-1) * pageSize;
        return sportRecords.stream()
                .map(po -> new SportBean().parseFromPo(po))
                .skip(pageStart)
                .limit(pageSize)
                .collect(Collectors.toList());
    }

    private LambdaQueryWrapper<DtrdEntRdSigninSportRecord> getBasicQueryWrapper(){
        return Wrappers.lambdaQuery(DtrdEntRdSigninSportRecord.class).eq(DtrdEntRdSigninSportRecord::getIsDel,0);
    }
}
